/*
 *    Copyright 2015 jack wang
 *    Copyright 2021 Institute of Software Chinese Academy of Sciences, ISRC

 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package com.wang.avi;

import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.HashMap;

public abstract class AVLoadingIndicatorView extends Component {

    private static final String TAG="AVLoadingIndicatorView";

    private int mMinWidth=200;

    private int mMaxWidth=400;

    private int mMinHeight=200;

    private int mMaxHeight=400;

    private Paint mPaint=new Paint();

    private Rect drawBounds = new Rect();

    private boolean mHasAnimators;

    private HashMap<AnimatorValue,AnimatorValue.ValueUpdateListener> mUpdateListeners=new HashMap<>();

    private ArrayList<AnimatorValue> mAnimators;

    public AVLoadingIndicatorView(Context context) {
        super(context);
    }

    public void setPaint(){
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mPaint.setAntiAlias(true);
    }

    public Paint getPaint(){
        return mPaint;
    }
    public void setBound(){
        //Add the offset
        int minValue=Math.min(getWidth(),getHeight());
        if (minValue>=getmMaxHeight() || minValue>=getmMaxWidth()){
            setWidth(getmMaxWidth());
            setHeight(getmMaxHeight());
        }else if(minValue<getmMinHeight() || minValue<getmMinWidth()){
            setWidth(getmMinWidth());
            setHeight(getmMinHeight());
        }else{
            setHeight(minValue);
            setWidth(minValue);
        }
    }

    public Rect getBound(){
        return drawBounds;
    }

    public abstract void draw(Canvas canvas, Paint paint);

    public abstract ArrayList<AnimatorValue> onCreateAnimators();

    public void addUpdateListener(AnimatorValue animator, AnimatorValue.ValueUpdateListener updateListener){
        mUpdateListeners.put(animator,updateListener);
    }

    private void startAnimators() {
        for (int i = 0; i < mAnimators.size(); i++) {
            AnimatorValue animator = mAnimators.get(i);
            //when the animator restart , add the updateListener again because they
            // was removed by animator stop .
            AnimatorValue.ValueUpdateListener updateListener=mUpdateListeners.get(animator);
            if (updateListener!=null){
                animator.setValueUpdateListener(updateListener);
            }
            animator.start();
        }
    }

    private void stopAnimators() {
        if (mAnimators!=null){
            for (AnimatorValue animator : mAnimators) {
                if (animator != null) {
                    animator.end();
                }
            }
        }
    }

    private void ensureAnimators() {
        if (!mHasAnimators) {
            mAnimators = onCreateAnimators();
            mHasAnimators = true;
        }
    }

    public void stop() {
        stopAnimators();
    }
    public void start() {
        ensureAnimators();
        startAnimators();
    }

    @Override
    public void setVisibility(int v) {
        if (getVisibility() != v) {
            super.setVisibility(v);
            if (v==HIDE || v == INVISIBLE) {
                stopAnimators();
            } else {
                startAnimators();
            }
        }
    }

    public void show(){
        setVisibility(VISIBLE);
    }

    public void hide(){
        setVisibility(HIDE);
    }

    //Setter and Getter
    public int getmMinWidth() {
        return mMinWidth;
    }

    public void setmMinWidth(int mMinWidth) {
        this.mMinWidth = mMinWidth;
    }

    public int getmMaxWidth() {
        return mMaxWidth;
    }

    public void setmMaxWidth(int mMaxWidth) {
        this.mMaxWidth = mMaxWidth;
    }

    public int getmMinHeight() {
        return mMinHeight;
    }

    public void setmMinHeight(int mMinHeight) {
        this.mMinHeight = mMinHeight;
    }

    public int getmMaxHeight() {
        return mMaxHeight;
    }

    public void setmMaxHeight(int mMaxHeight) {
        this.mMaxHeight = mMaxHeight;
    }

}
